#import "AliPlugin.h"
#import <CloudPushSDK/CloudPushSDK.h>
#import <AlipaySDK/AlipaySDK.h>

@implementation AliPlugin
FlutterMethodChannel* channel;
NSString* _deviceid;
BOOL _isRegisted = NO;
NSString* _account;
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  channel = [FlutterMethodChannel
      methodChannelWithName:@"ali_plugin"
            binaryMessenger:[registrar messenger]];
  AliPlugin* instance = [[AliPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else if([@"getDeviceId" isEqualToString:call.method]){
      result(_deviceid);
  } else if([@"toAuth" isEqualToString:call.method]) {
      NSString* arguments = call.arguments;
      [self toAuth: arguments result: result];
  } else if([@"payOrder" isEqualToString:call.method]) {
      NSString* arguments = call.arguments;
      [self payOrder: arguments result: result];
  } else if([@"bindAccount" isEqualToString:call.method]){
      NSString* account = call.arguments;
      [self bindAccount: account];
  } else if([@"unBindAccount" isEqualToString:call.method]){
      [self unBindAccount];
  } else {
    result(FlutterMethodNotImplemented);
  }
}

- (void)initCloudPush {
    // 获取 info.plist 配置文件对应的 字典对象
    NSDictionary *info = [NSBundle mainBundle].infoDictionary;
    NSString* appKey = info[@"aliyun.appKey"];
    NSString* appSecret = info[@"aliyun.appSecret"];
    // SDK初始化
    [CloudPushSDK asyncInit:appKey appSecret:appSecret callback:^(CloudPushCallbackResult *res) {
        if (res.success) {
            NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]);
            _isRegisted = YES;
            if(_account != NULL && [_account length] > 0){
                [self bindAccount:_account];
            }
        } else {
            NSLog(@"Push SDK init failed, error: %@", res.error);
        }
    }];
}

- (void)bindAccount:(NSString*) account {
    _account = account;
    if(_isRegisted){
        [CloudPushSDK bindAccount: _account withCallback:^(CloudPushCallbackResult *res) {
            if (res.success) {
                _deviceid = [CloudPushSDK getDeviceId];
                [channel invokeMethod:@"onBindSuccess" arguments:_account];
                NSLog(@"Push SDK bindAccount success, deviceId: %@.", [CloudPushSDK getDeviceId]);
            } else {
                [channel invokeMethod:@"onBindFailed" arguments:res.error];
                NSLog(@"Push SDK bindAccount failed, error: %@", res.error);
            }
        }];
    }else{
        [self initCloudPush];
    }
}

- (void)unBindAccount {
    [CloudPushSDK unbindAccount: ^(CloudPushCallbackResult *res) {
        if (res.success) {
            [channel invokeMethod:@"unBindSuccess" arguments:NULL];
            NSLog(@"Push SDK unbindAccount success");
        } else {
            [channel invokeMethod:@"unBindFailed" arguments:res.error];
            NSLog(@"Push SDK unbindAccount failed, error: %@", res.error);
        }
    }];
}
/**
 *    注册苹果推送，获取deviceToken用于推送
 */
- (void)registerAPNS:(UIApplication *)application {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        // iOS 8 Notifications
        [application registerUserNotificationSettings:
         [UIUserNotificationSettings settingsForTypes:
          (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
                                           categories:nil]];
        [application registerForRemoteNotifications];
    }
    else {
//        // iOS < 8 Notifications
//        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
//         (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
    }
}

-(void)listenOnChannelOpened {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wundeclared-selector"
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChannelOpened:)
    name:@"CCPDidChannelConnectedSuccess"
    object:nil];
    #pragma clang diagnostic pop
}


/*
 *  苹果推送注册成功回调，将苹果返回的deviceToken上传到CloudPush服务器
 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
        if (res.success) {
            NSLog(@"Register deviceToken success.");
        } else {
            NSLog(@"Register deviceToken failed, error: %@", res.error);
        }
    }];
}
/*
 *  苹果推送注册失败回调
 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"didFailToRegisterForRemoteNotificationsWithError %@", error);
}

/**
 *    注册推送消息到来监听
 */
- (void)registerMessageReceive {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onMessageReceived:)
                                                 name:@"CCPDidReceiveMessageNotification"
                                               object:nil];
}
/**
 *    处理到来推送消息
 */
- (void)onMessageReceived:(NSNotification *)notification {
    CCPSysMessage *message = [notification object];
    NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding];
    NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding];
    NSLog(@"Receive message title: %@, content: %@.", title, body);
}

/**
 * 通知打开监听
 */
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 点击通知将App从关闭状态启动时，将通知打开回执上报
    // [CloudPushSDK handleLaunching:launchOptions];(Deprecated from v1.8.1)
    [CloudPushSDK sendNotificationAck:launchOptions];
    
    // APNs注册，获取deviceToken并上报
    [self registerAPNS: application];
    // 初始化阿里云推送SDK
    [self initCloudPush];
       // 监听推送通道打开动作
    [self listenOnChannelOpened];
    // 监听推送消息到达
    [self registerMessageReceive];
    // 点击通知将App从关闭状态启动时，将通知打开回执上报
    [CloudPushSDK sendNotificationAck: launchOptions];
    return YES;
}
/*
 *  App处于启动状态时，通知打开回调
 */
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {
    NSLog(@"Receive one notification.");
    // 取得APNS通知内容
    NSDictionary *aps = [userInfo valueForKey:@"aps"];
    // 内容
    NSString *content = [aps valueForKey:@"alert"];
    // badge数量
    NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
    // 播放声音
    NSString *sound = [aps valueForKey:@"sound"];
    // 取得Extras字段内容
    NSString *Extras = [userInfo valueForKey:@"Extras"]; //服务端中Extras字段，key是自己定义的
    NSLog(@"content = [%@], badge = [%ld], sound = [%@], Extras = [%@]", content, (long)badge, sound, Extras);
    // iOS badge 清0
    application.applicationIconBadgeNumber = 0;
    // 通知打开回执上报
    // [CloudPushSDK handleReceiveRemoteNotification:userInfo];(Deprecated from v1.8.1)
    [CloudPushSDK sendNotificationAck:userInfo];
}


- (BOOL)application:(UIApplication*)application
          openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
       annotation:(id)annotation
{
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付，处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            [channel invokeMethod:@"payCallBack" arguments:resultDic];
        }];
        
        // 授权跳转支付宝钱包进行支付，处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            [channel invokeMethod:@"authCallBack" arguments:resultDic];
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options
{
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付，处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            [channel invokeMethod:@"payCallBack" arguments:resultDic];
        }];
        
        // 授权跳转支付宝钱包进行支付，处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            [channel invokeMethod:@"authCallBack" arguments:resultDic];
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

- (void)toAuth:(NSString*)arguments result:(FlutterResult) result {
    [[AlipaySDK defaultService] auth_V2WithInfo:arguments
    fromScheme:@"ali_plugin"
      callback:^(NSDictionary *resultDic) {
          NSLog(@"result = %@",resultDic);
          // 解析 auth code
          NSString *result = resultDic[@"result"];
          NSString *authCode = nil;
        [channel invokeMethod:@"authCallBack" arguments:resultDic];
          if (result.length>0) {
              NSArray *resultArr = [result componentsSeparatedByString:@"&"];
              for (NSString *subResult in resultArr) {
                  if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                      authCode = [subResult substringFromIndex:10];
                      break;
                  }
              }
          }
          NSLog(@"授权结果 authCode = %@", authCode?:@"");
      }];
}


- (void)payOrder:(NSString*)arguments result:(FlutterResult) result {
    [[AlipaySDK defaultService] payOrder:arguments
    fromScheme:@"alipay"
      callback:^(NSDictionary *resultDic) {
          NSLog(@"result = %@",resultDic);
        [channel invokeMethod:@"payCallBack" arguments:resultDic];
      }];
}


@end
